package net.thxjj.adminServer.service.impl;

import com.alibaba.fastjson.JSONObject;
import net.thxjj.adminServer.dao.UserApiDao;
import net.thxjj.adminServer.entity.*;
import net.thxjj.adminServer.service.IMenuService;
import net.thxjj.adminServer.service.IUserApiService;
import net.thxjj.adminServer.util.JWTUtils;
import net.thxjj.adminServer.util.ParameterMap;
import net.thxjj.adminServer.util.RightsHelper;
import net.thxjj.adminServer.util.SHA;
import net.thxjj.sitermodel.Menu;
import net.thxjj.sitermodel.Role;
import net.thxjj.sitermodel.User;
import net.thxjj.sitermodel.UserRole;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class UserApiService implements IUserApiService {
    private Logger log = Logger.getLogger(this.getClass());
    @Autowired
    private UserApiDao userApiDao;
    @Autowired
    private IMenuService menuService;

    @Override
    public Long getUserByToken(String token) {

        return userApiDao.getUserByToken(token);
    }

    @Override
    public User getUserInfoByToken(String token) {
        return userApiDao.getUserInfoByToken(token);
    }

    @Override
    public HashMap<String, Object> Login(String username, String password) {
        try {

            ParameterMap pm = new ParameterMap();
            password = SHA.encryptSHA(password);
            pm.put("password", password);
            pm.put("username", username);
            User user = userApiDao.getUserInfo(pm);

            if(user==null) return ResponseModel.getModel(ResultEnum.LOGIN_PASSWORD_ERROR, null);

            if(user.getStatus()!=0){
                return ResponseModel.getModel(ResultEnum.USER_IS_LOCK_ERROR, null);
            }

            //获取用户权限
            Long userId = user.getUser_id();
            pm.put("user_id", userId);
            //获取用户所有角色
            List<Role> uRoles = userApiDao.getUserRoleList(pm);
            long maxMenuId = menuService.getMaxId();
            UserRole uRole = new UserRole(new BigInteger("0"),new BigInteger("0"),new BigInteger("0"),new BigInteger("0"),new BigInteger("0"));
            checkUserRole(uRoles, uRole, maxMenuId);
            user.setUserRole(uRole);
            List<Menu> oneMenuList = menuService.getAllMenuList();

            long currenttime = System.currentTimeMillis();
            //生成access_token
            ParameterMap parameterMap_acc = new ParameterMap();
            parameterMap_acc.put("user_id",user.getUser_id());
            parameterMap_acc.put("current_time",currenttime);
            String ad = JSONObject.toJSON(parameterMap_acc).toString();
            String token =  JWTUtils.ProduceToken(ad);
            user.setToken(token);
            List<String> permissionCodes = getPermissionMenu(oneMenuList,uRole.getRights());
            user.setPermissionCodes(permissionCodes);
            ParameterMap map = new ParameterMap();
            map.put("token",token);
            map.put("loginSysUserVo",user);
            ParameterMap condition = new ParameterMap();
            condition.put("user_id", userId);
            condition.put("token", token);
            condition.put("token_time", currenttime);
            userApiDao.updateToken(condition);
            return ResponseModel.getModel(ResultEnum.SUCCESS_LOGIN, map);
        }catch (Exception e) {
            e.printStackTrace();
            log.error("login error :" + e.getMessage(), e);
            return ResponseModel.getModel(ResultEnum.ERROR, null);
        }

    }


    /**
     * 动态菜单校验
     *
     * @param oneMenuList
     *            总菜单
     * @param rights
     *            用户权限值
     */
    public List<String> getPermissionMenu(List<Menu> oneMenuList, BigInteger rights) {
        List<String> list = new ArrayList<String>();
        for (Menu m : oneMenuList) {
            m.setHasMenu(RightsHelper.testRights(rights, m.getMENU_ID()));
            if (m.isHasMenu()) {
                List<Menu> subList = m.getSubMenu();
                for (Menu subM : subList) {
                    if(RightsHelper.testRights(rights, subM.getMENU_ID())){
                        list.add(subM.getCode()+":management");
                    }

                }
            }
        }
        return list;
    }

    /**
     * 把用户拥有的角色权限合并起来
     * @param uRoles
     * @param uRole
     * @param maxMenuId
     */
    public void checkUserRole(List<Role> uRoles,UserRole uRole,long maxMenuId){
        if(uRoles == null){return;}
        for(int i=0;i<uRoles.size();i++){
            BigInteger right = new BigInteger(uRoles.get(i).getRights());
            BigInteger aqx = new BigInteger(uRoles.get(i).getAddQX());
            BigInteger dqx = new BigInteger(uRoles.get(i).getDelQX());
            BigInteger eqx = new BigInteger(uRoles.get(i).getEditQX());
            BigInteger qqx = new BigInteger(uRoles.get(i).getQueryQX());
            for(int j=0;j<=maxMenuId;j++){
                if(right.testBit(j)){
                    uRole.setRights(uRole.getRights().setBit(j));
                }
                if(aqx.testBit(j)){
                    uRole.setAdds_qx(uRole.getAdds_qx().setBit(j));
                }
                if(dqx.testBit(j)){
                    uRole.setDels_qx(uRole.getDels_qx().setBit(j));
                }
                if(eqx.testBit(j)){
                    uRole.setEdits_qx(uRole.getEdits_qx().setBit(j));
                }
                if(qqx.testBit(j)){
                    uRole.setQuerys_qx(uRole.getQuerys_qx().setBit(j));
                }
            }
        }
    }
}
